#ifndef QSLOGDEST_H
#define QSLOGDEST_H

#include "QsLogLevel.h"
#include <QSharedPointer>
#include <QtGlobal>
class QString;
class QObject;

#ifdef QSLOG_IS_SHARED_LIBRARY
#define QSLOG_SHARED_OBJECT Q_DECL_EXPORT
#elif QSLOG_IS_SHARED_LIBRARY_IMPORT
#define QSLOG_SHARED_OBJECT Q_DECL_IMPORT
#else
#define QSLOG_SHARED_OBJECT
#endif

namespace QsLogging
{

class QSLOG_SHARED_OBJECT Destination
{
public:
    typedef void (*LogFunction)(const QString &message, Level level);

public:
    // 虚析构函数
    virtual ~Destination();
    // 写入日志消息到目标
    virtual void write(const QString& message, Level level) = 0;
    // 检查目标是否有效
    virtual bool isValid() = 0; // 返回目标是否创建正确
};
typedef QSharedPointer<Destination> DestinationPtr;


// 一系列"命名"参数，使文件目标创建更具可读性
enum LogRotationOption
{
    DisableLogRotation = 0, // 禁用日志轮转
    EnableLogRotation  = 1  // 启用日志轮转
};

struct QSLOG_SHARED_OBJECT MaxSizeBytes
{
    // 默认构造函数
    MaxSizeBytes() : size(0) {}
    // 带参数的构造函数
    explicit MaxSizeBytes(qint64 size_) : size(size_) {}
    qint64 size;
};

struct QSLOG_SHARED_OBJECT MaxOldLogCount
{
    // 默认构造函数
    MaxOldLogCount() : count(0) {}
    // 带参数的构造函数
    explicit MaxOldLogCount(int count_) : count(count_) {}
    int count;
};


//! 创建日志目标/接收器。调用者与记录器共享目标的所有权。
//! 添加到记录器后，调用者可以丢弃指针。
class QSLOG_SHARED_OBJECT DestinationFactory
{
public:
    // 创建文件目标
    static DestinationPtr MakeFileDestination(const QString& filePath,
        LogRotationOption rotation = DisableLogRotation,
        const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(),
        const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount());
    // 创建调试输出目标
    static DestinationPtr MakeDebugOutputDestination();
    // 创建函数目标，接受指向函数的指针
    static DestinationPtr MakeFunctorDestination(Destination::LogFunction f);
    // 创建函数目标，接受 QObject + 信号/槽
    static DestinationPtr MakeFunctorDestination(QObject *receiver, const char *member);
};

} // 命名空间结束

#endif // QSLOGDEST_H
